package com.platform.user.service;

import com.platform.exception.BadRequestException;
import com.platform.user.dao.AdminDao;
import com.platform.user.entity.Admin;
import com.platform.user.entity.MyAdminDetails;
import lombok.NoArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Map;

@Service
@NoArgsConstructor
// UserDetailsService负责根据用户名查找用户,UserDetailsPasswordService负责更新密码,现在把这两个接口封装成MyUserDetailService
// TODO 留给业务模块重写此类（MyUserDetailService），因为这个类需要连接具体数据库，但web模块只提供通用的配置
public class MyAdminDetailService implements UserDetailsService, UserDetailsPasswordService {

    @Resource
    private AdminDao adminDao;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
//    当调用updatePassword()方法时，可以在具体的实现中根据需要进行密码加密,即使用户输入的新密码是明文形式，也可以在该方法内部使用合适的加密方式对密码进行加密并保存到存储中
//    默认使用的是DelegatingPasswordEncoder中的Bcrypt方式加密,如果需要指定用户升级密码的加密方式,就需要在securityConfig中对PasswordEncoder实现并写入spring工厂就行了
//    虽然在其它地方没有调用updatePassword方法,但在用户每次登录成功时,会自动更新用户的密码编码方式,并且存储在数据库中
    public UserDetails updatePassword(UserDetails user, String newPassword) {
////        调用mapper修改数据库中的密码,newPassword是新的密码,包括新的编码方式或者新的密码明文,返回的是判断有没有更新密码的结果
//        Integer result = userDao.updatePassword(user.getUsername(), newPassword);
//        System.out.println("newPassword:" + newPassword);
//        if(result == 1) {
////            如果为1,说明数据库中的密码修改成功,就需要把实体类对象user里面的密码也进行更新
//            ((MyUserDetails) user).getUser().setPassword(newPassword);
//        }
//        return user;
        return null;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Admin admin = adminDao.queryByUsername(username);
        if(ObjectUtils.isEmpty(admin)) {
            return null;
        }
        return new MyAdminDetails(admin, admin.getUsername(), admin.getPassword());
    }

    public Admin queryAdminByUsername(String username) {
        if (username == null || username.isEmpty()) {
            throw new BadRequestException("用户名为空");
        }
        return adminDao.queryByUsername(username);
    }

    public int addAdmin(Map<String, Object> params) {
        String password = (String) params.get("password");
        params.put("password", passwordEncoder.encode(password));
        return adminDao.insert(setAdminByParams(params));
    }

    private Admin setAdminByParams(Map<String, Object> params) {
        String username = (String) params.get("username");
        String password = (String) params.get("password");
        String fullName = (String) params.get("fullName");
        int identity = (int) params.get("identity");
        String academy = (String) params.get("academy");
        String major = (String) params.get("major");
        String email = (String) params.get("email");

        Admin admin = new Admin();
        admin.setUsername(username);
        admin.setPassword(password);
        admin.setEmail(email);
        admin.setFullName(fullName);
        admin.setIdentity(identity);
        admin.setMajor(major);
        admin.setAcademy(academy);

        return admin;
    }
}
